#include <portaudio.h>
#include <iostream>
#include "utool_AudioRT/Audio_RT_Base.h"
#include "utool_AudioRT/Config.h"
#include <vector>
#include <deque>
#include <algorithm>
#include "utool_AudioRT/Audio_RT_Process.h"
#include <fstream>
#include "utool_AudioRT/Audio_RT_FFT.h"
#include <string.h>
#include <chrono> // 记录回调函数运行时间
#include "utool_AudioRT/SPE_Tradition.h"
#include "utool_AudioRT/SPE_BeamForming.h"
#include <sndfile.h>   // libsndfile 头文件
// 定义时间缓存队列,直接定义四路的队列用于存储麦克风数据
std::deque<std::deque<__fp16>> Time_Cache_LH( // 左前
    NUM_TIME,                     // 行数
    std::deque<__fp16>(WINDOW_SIZE, __fp16(0.0f)) // 每行初始化为包含 WINDOW_SIZE 个元素的 deque
);
std::deque<std::deque<__fp16>> Time_Cache_LB( // 左后
    NUM_TIME,                     // 行数
    std::deque<__fp16>(WINDOW_SIZE, __fp16(0.0f)) // 每行初始化为包含 WINDOW_SIZE 个元素的 deque
);
std::deque<std::deque<__fp16>> Time_Cache_RH( // 右前
    NUM_TIME,                     // 行数
    std::deque<__fp16>(WINDOW_SIZE, __fp16(0.0f)) // 每行初始化为包含 WINDOW_SIZE 个元素的 deque
);
std::deque<std::deque<__fp16>> Time_Cache_RB( // 右后
    NUM_TIME,                     // 行数
    std::deque<__fp16>(WINDOW_SIZE, __fp16(0.0f)) // 每行初始化为包含 WINDOW_SIZE 个元素的 deque
);

// 
std::vector<std::vector<__fp16>> Time_Cache_Matrix_LH; // 进行数组操作的原型数组--左前
std::vector<std::vector<__fp16>> Time_Cache_Matrix_LB; // 进行数组操作的原型数组--左后
std::vector<std::vector<__fp16>> Time_Cache_Matrix_RH; // 进行数组操作的原型数组--右前
std::vector<std::vector<__fp16>> Time_Cache_Matrix_RB; // 进行数组操作的原型数组--右后



std::vector<__fp16> Anly_Windows; // 分析窗口
std::vector<__fp16> Sys_Windows; // 分析窗口
std::vector<__fp16> result_AddSys; // 最后处理两帧叠加综合窗的结果
std::vector<std::vector<__fp16>> mag_LH, phase_LH; // 幅度谱和相位谱结果--左前
std::vector<std::vector<__fp16>> mag_LB, phase_LB; // 幅度谱和相位谱结果--左后
std::vector<std::vector<__fp16>> mag_RH, phase_RH; // 幅度谱和相位谱结果--右前
std::vector<std::vector<__fp16>> mag_RB, phase_RB; // 幅度谱和相位谱结果--右后
// 创建处理器
FFTProcessor RTFFT_processor;
// 传统语音增强的参数
std::vector<std::vector<__fp16>> SPE_mag; // 语音增强后的谱
std::vector<__fp16> Noise_mag(FFT_BINS, (__fp16)0); // 参考噪声谱

// 进行WDRC后的频谱
std::vector<std::vector<__fp16>> WDRC_mag;
// 进行FC后的频谱
std::vector<std::vector<__fp16>> FC_mag;
// WDRC的增益表格
std::vector<std::vector<__fp16>> WDRC_Table;
// FC的增益表格
std::vector<std::vector<__fp16>> FC_Table;
std::vector<__fp16> FC_CSRvalues;
std::vector<int> col_idx;
std::vector<int> row_ptr;
// 逆向变换
std::vector<std::vector<__fp16>> reconstructed_Time;





// 测试变量，把音频的输入输出存储下来煮酒
// 全局变量存储输入和输出的音频数据（16kHz * 20s = 320000 samples）
int time_num = 10;
std::vector<float> g_input_buffer_LH(time_num*16000, 0.0f);  // 输入缓存
std::vector<float> g_input_buffer_LB(time_num*16000, 0.0f);  // 输入缓存
std::vector<float> g_input_buffer_RH(time_num*16000, 0.0f);  // 输入缓存
std::vector<float> g_input_buffer_RB(time_num*16000, 0.0f);  // 输入缓存
std::vector<float> g_output_buffer(time_num*16000, 0.0f); // 输出缓存
unsigned int g_sample_counter = 0;                // 样本计数器



// 用于指定当前要进行音频塞入的行数
int input_num = 0; 
int hopsize_num = WINDOW_SIZE / HOP_SIZE; // 每一行的Hopsize数
int max_input_num = NUM_TIME + hopsize_num - 1;
int index_num = 0; //用于指定的行数
int move_up_flage = 0; //用于指定是否整体数组上移
int matrix_copy_flage = 0; //用于判断是否已经从队列中复制了数组数据
std::vector<float> read_pcm16(const std::string& filename) {
    std::ifstream file(filename, std::ios::binary | std::ios::ate);
    if (!file) {
        std::cerr << "无法打开文件: " << filename << std::endl;
        return {};
    }

    // 文件总大小
    std::streamsize size = file.tellg();
    file.seekg(0, std::ios::beg);

    if (size % sizeof(int16_t) != 0) {
        std::cerr << "文件大小不是 2 的倍数，可能不是裸 PCM16!" << std::endl;
        return {};
    }

    // 样本数
    size_t num_samples = size / sizeof(int16_t);

    // 直接分配 int16_t buffer
    std::vector<int16_t> buffer_int16(num_samples);

    // 真正读取
    file.read(reinterpret_cast<char*>(buffer_int16.data()), size);
    if (!file) {
        std::cerr << "读取失败，只读到 " << file.gcount() << " 字节" << std::endl;
    }

    // 转换为 float [-1, 1]
    std::vector<float> buffer_float(num_samples);
    for (size_t i = 0; i < num_samples; i++) {
        buffer_float[i] = static_cast<float>(buffer_int16[i]) / 32768.0f;
    }

    return buffer_float;
}

int main(int argc, char **argv)
{
    SF_INFO sfinfo_LH = {}; // 必须初始化为 0
    SNDFILE* infile_LH = sf_open("input_LH.wav", SFM_READ, &sfinfo_LH);
    if (!infile_LH) {
        std::cerr << "无法打开文件: " << sf_strerror(NULL) << std::endl;
        return -1;
    }

    SF_INFO sfinfo_LB = {};
    SNDFILE* infile_LB = sf_open("input_LB.wav", SFM_READ, &sfinfo_LB);
    if (!infile_LB) {
        std::cerr << "无法打开文件: " << sf_strerror(NULL) << std::endl;
        sf_close(infile_LH);
        return -1;
    }

    // 确认采样率和通道数
    if (sfinfo_LH.channels != 1 || sfinfo_LB.channels != 1) {
        std::cerr << "目前只支持单通道 WAV 文件" << std::endl;
        sf_close(infile_LH);
        sf_close(infile_LB);
        return -1;
    }

    // 分配缓冲区
    std::vector<float> buffer_LH(sfinfo_LH.frames);
    std::vector<float> buffer_LB(sfinfo_LB.frames);

    // 读取全部帧
    sf_readf_float(infile_LH, buffer_LH.data(), sfinfo_LH.frames);
    sf_readf_float(infile_LB, buffer_LB.data(), sfinfo_LB.frames);

    sf_close(infile_LH);
    sf_close(infile_LB);

    // 生成分析窗(输入FFT的时域加窗)
    Anly_Windows = asymmetric_Analy_windows(HOP_SIZE,WINDOW_SIZE,10);
    // 生成综合窗(IFFT输出的时域结果加窗)
    Sys_Windows = asymmetric_Sys_windows(HOP_SIZE,WINDOW_SIZE,10);



    // 输出文件
    SF_INFO sfinfo_out;
    sfinfo_out.channels = 2;   // 立体声
    sfinfo_out.samplerate = SAMPLE_RATE;
    sfinfo_out.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
    SNDFILE* outfile = sf_open("output_test.wav", SFM_WRITE, &sfinfo_out);


    // ------------------- 处理参数初始化 -------------------
    int input_num = 0;
    int max_input_num = NUM_TIME + hopsize_num - 1;
    int hopsize_num = WINDOW_SIZE / HOP_SIZE;
    int index_num = 0;
    int move_up_flage = 0;
    int matrix_copy_flage = 0;

    int Test_Flag = 0;
    int Test_Frame_Num = 0;

    // ------------------- hop 循环 -------------------
    size_t total_frames = std::min(buffer_LH.size(), buffer_LB.size());
    for (size_t pos = 0; pos + HOP_SIZE <= total_frames; pos += HOP_SIZE) {
        // 每次取 hop_size 数据
        std::vector<audio_sample_IN> input(HOP_SIZE);
        for (int i = 0; i < HOP_SIZE; i++) {
            input[i].left_H = buffer_LH[pos + i];
            input[i].left_B = buffer_LB[pos + i];
            if(input[i].left_H != 0)
            {
                Test_Flag = 1;
            }
        }
        std::vector<audio_sample_OUT> output(HOP_SIZE);

        // ------------------- 替代 audioCallback 的逻辑 -------------------
        input_num++;
        if (input_num > max_input_num) {
            input_num = max_input_num;
            move_up_flage = 1;
        }
        index_num = std::max(input_num - hopsize_num, 0);

        if (move_up_flage == 1) {
            deque_move_up(Time_Cache_LH);
            deque_move_up(Time_Cache_LB);
        }
        if (index_num >= 1) {
            deque_copy_start_tar(Time_Cache_LH, index_num - 1, index_num);
            deque_copy_start_tar(Time_Cache_LB, index_num - 1, index_num);
        }

        for (unsigned int i = 0; i < HOP_SIZE; i++) {
            if (index_num == 0) {
                Time_Cache_LH[index_num].pop_front();
                Time_Cache_LH[index_num].push_back(static_cast<__fp16>(input[i].left_H));

                Time_Cache_LB[index_num].pop_front();
                Time_Cache_LB[index_num].push_back(static_cast<__fp16>(input[i].left_B));
            } else {
                Time_Cache_LH[index_num][HOP_SIZE*(hopsize_num - 1) + i] = input[i].left_H;
                Time_Cache_LB[index_num][HOP_SIZE*(hopsize_num - 1) + i] = input[i].left_B;
            }
        }

        if (input_num == max_input_num) {
            // 在这里面进行音频的算法流处理
            // 1.先复制上面的二维队列到数组中以方便操作
            if(matrix_copy_flage == 0){ // 还没复制队列数据，要开始复制队列数据
                // 把四路麦克风队列变数组
                Time_Cache_Matrix_LH = deque_to_matrix(Time_Cache_LH);
                Time_Cache_Matrix_LB = deque_to_matrix(Time_Cache_LB);

                //变数组完成
                matrix_copy_flage = 1;
                // 添加窗函数，每一帧都添加分析窗函数
                Time_Cache_Matrix_LH = apply_window_multiply(Time_Cache_Matrix_LH,Anly_Windows);
                Time_Cache_Matrix_LB = apply_window_multiply(Time_Cache_Matrix_LB,Anly_Windows);

                // 把添加了窗函数的时域信号直接进行FFT，然后返回幅度谱和相位谱
                RTFFT_processor.compute_spectrum(Time_Cache_Matrix_LH, mag_LH, phase_LH); 
                RTFFT_processor.compute_spectrum(Time_Cache_Matrix_LB, mag_LB, phase_LB); 
                // // 进行WDRC
                // RT_WDRC(mag,WDRC_mag);
                RTFFT_processor.reconstruct_signal(mag_LH, phase_LH, reconstructed_Time);
            }
            else{ 
                // 左前
                shift_matrix_up(Time_Cache_Matrix_LH,Time_Cache_LH); // 把数组整体上移一位，并且把队列的最后一行数据放到数组最后一行中
                // 添加分析窗函数(只对最后一行)
                multiply_last_n_rows_inplace(Time_Cache_Matrix_LH,Anly_Windows,1);
                // mag和phase向上移动一行，并且把加窗了的时域进行FFT后分别补充到mag和phase
                shift_matrix_MAG_PHASE_up(Time_Cache_Matrix_LH, mag_LH, phase_LH, RTFFT_processor);

                // 先注释一下
                // 左后
                shift_matrix_up(Time_Cache_Matrix_LB,Time_Cache_LB); // 把数组整体上移一位，并且把队列的最后一行数据放到数组最后一行中
                // 添加分析窗函数(只对最后一行)
                multiply_last_n_rows_inplace(Time_Cache_Matrix_LB,Anly_Windows,1);
                // mag和phase向上移动一行，并且把加窗了的时域进行FFT后分别补充到mag和phase
                shift_matrix_MAG_PHASE_up(Time_Cache_Matrix_LB, mag_LB, phase_LB, RTFFT_processor);
                // // 进行语音增强
                // Spe_Sub(mag_LH,SPE_mag,Noise_mag);
                // 进行麦克风阵列的输出
                // DeNoise_MutileSpeech(mag_LH,phase_LH,mag_LB,phase_LB,SPE_mag);
                // 把mag和phase结合，只对最后两行进行IFFT
                RTFFT_processor.reconstruct_signal_Only(SPE_mag, phase_LH, reconstructed_Time);
            }
            // 最后两行乘上综合窗并进行叠加还原
            result_AddSys = Generate_SysResult(reconstructed_Time,Sys_Windows,2);
            // 输出
            for (unsigned int i = 0; i < HOP_SIZE; ++i) {
                output[i].left = result_AddSys[i];
                output[i].right = result_AddSys[i];
            }
        }
        Test_Frame_Num++;
        // 写入文件
        std::vector<float> interleaved(HOP_SIZE * 2);
        for (int i = 0; i < HOP_SIZE; i++) {
            interleaved[2*i]   = output[i].left;
            interleaved[2*i+1] = output[i].right;
        }
        sf_writef_float(outfile, interleaved.data(), HOP_SIZE);
    }

    sf_close(outfile);
    std::cout << "处理完成，输出到 output_test.wav" << std::endl;
    return 0;
}